/*
 * Copyright (c) 2021-2021 harkue
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.harkue.pkglock.integrity;


import org.apache.commons.codec.digest.DigestUtils;
import org.harkue.pkglock.PkgConstants;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

/**
 * NPM Package加密器
 *
 * @author harkue
 * @date 2021/12/18
 */
public class PkgEncryptor {
    /**
     * 根据加密算法，获取文件的Hash值进行完整校验
     *
     * @param file      文件
     * @param algorithm 算法
     * @return Hash值
     */
    public String getFileHash(File file, String algorithm) throws Exception {
        String hash = null;
        try (InputStream inputStream = new FileInputStream(file)) {
            hash = getInputStreamHash(inputStream, algorithm);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return hash;
    }

    /**
     * 根据NPM包输入流， 计算文件的Hash值
     *
     * @param inputStream NPM包输入流
     * @param algorithm   算法
     * @return 文件Hash值
     * @throws Exception 算法不存在，抛出异常
     */
    public String getInputStreamHash(InputStream inputStream, String algorithm) throws Exception {
        String hash;

        if (PkgConstants.MD5.equals(algorithm)) {
            hash = Base64.getEncoder().encodeToString(DigestUtils.md5(inputStream));
        } else if (PkgConstants.SHA1.equals(algorithm)) {
            hash = Base64.getEncoder().encodeToString(DigestUtils.sha1(inputStream));
        } else if (PkgConstants.SHA256.equals(algorithm)) {
            hash = Base64.getEncoder().encodeToString(DigestUtils.sha256(inputStream));
        } else {
            throw new Exception("not support this algorithm " + algorithm);
        }

        return hash;
    }

    public String getSha256(File file) throws Exception {
        return getFileHash(file, "sha256");
    }

    public String getSha256(InputStream inputStream) throws Exception {
        return getInputStreamHash(inputStream, "sha256");
    }

    public String getMd5(File file) throws Exception {
        return getFileHash(file, "md5");
    }

    public String getMd5(InputStream inputStream) throws Exception {
        return getInputStreamHash(inputStream, "md5");
    }
}
